﻿using System;

using DDDSample.Common.Validate;
using DDDSample.Domain.Model.Carrier;
using DDDSample.Domain.Model.Locations;

namespace DDDSample.Domain.Model.Cargos
{
	/// <summary>
	/// An itinerary consists of one or more legs.
	/// </summary>
	public sealed class Leg : ValueObject<Leg>
	{
		private CarrierMovement carrierMovement;
		private Location from;
		private Location to;

		/// <summary>
		/// Constructor.
		/// </summary>
		/// <param name="carrierMovement"></param>
		/// <param name="from"></param>
		/// <param name="to"></param>
		public Leg(CarrierMovement carrierMovement, Location from, Location to)
		{
			Validate.NotNull(carrierMovement);
			Validate.NotNull(from);
			Validate.NotNull(to);
			this.carrierMovement = carrierMovement;
			this.from = from;
			this.to = to;
		}

		public CarrierMovement CarrierMovement
		{
			get { return this.carrierMovement; }
		}

		public Location From
		{
			get { return this.from; }
		}

		public Location To
		{
			get { return this.to; }
		}

		public override bool SameValueAs(Leg other)
		{
			return other != null &&
				this.carrierMovement.SameIdentityAs(other.carrierMovement) &&
				this.from.SameIdentityAs(other.from) &&
				this.to.SameIdentityAs(other.to);
		}

		public override bool Equals(object obj)
		{
			if (this == obj) return true;
			if (obj == null || GetType() != obj.GetType()) return false;

			Leg other = (Leg)obj;

			return SameValueAs(other);
		}

		public override int GetHashCode()
		{
			int hashCode = 37 + this.carrierMovement.GetHashCode();
			hashCode += hashCode * 17 + this.from.GetHashCode();
			hashCode += hashCode * 17 + this.to.GetHashCode();
			return hashCode;
		}

		private Leg()
		{
			// Needed by Hibernate
		}

		// Auto-generated surrogate key
		private long id;
	}
}
